﻿using System;
using System.Collections.Generic;
using System.Linq;
using libEngineAI;
using libEngineAI.Interfaces;

namespace libGameCheckers.Boards
{
	public class ConsoleBoard : IBoard, IPlayer
	{
		#region IPlayer implementation

		public Movement GetMovement( IGame Game )
		{
			Movement mov = null;
			IPiece PtoMove = null;

			IEnumerable<Movement> Moves = Game.GenerateMoves();

			while( mov == null )
			{
				int ActualX = Console.CursorLeft;
				int ActualY = Console.CursorTop;

				ConsoleKeyInfo k = Console.ReadKey();
				Console.CursorVisible = false;
				switch( k.Key )
				{
					case ConsoleKey.LeftArrow:
						if( Console.CursorLeft > 4 )
							Console.CursorLeft = Console.CursorLeft - 4;
						else
							Console.CursorLeft = 3;

						break;

					case ConsoleKey.UpArrow:
						if( Console.CursorTop > 3 )
						{
							Console.CursorTop = Console.CursorTop - 1;
							Console.CursorLeft = Console.CursorLeft - 1;
						}
						else
							Console.CursorLeft = Console.CursorLeft - 1;

						break;

					case ConsoleKey.RightArrow:
						if( Console.CursorLeft < ( MaxCoordinates.x * 3 ) + 1 )
							Console.CursorLeft = Console.CursorLeft + 2;
						else
							Console.CursorLeft = MaxCoordinates.x * 3;

						break;

					case ConsoleKey.DownArrow:
						if( Console.CursorTop < ( MaxCoordinates.y ) + 2 )
						{
							Console.CursorTop = Console.CursorTop + 1;
							Console.CursorLeft = Console.CursorLeft - 1;
						}
						else
							Console.CursorLeft = Console.CursorLeft - 1;


						break;

					case ConsoleKey.Enter:
						Console.CursorTop = ActualY;
						Console.CursorLeft = ActualX;

						Coordinate coord = ConsoleCoords2BoardCoords();

						/*IPiece p = ( from a in Game.Pieces
						             where a.Coordinates.Equals( coord )
						             select a ).FirstOrDefault();
						             */
						IPiece p = Game.Pieces.FirstOrDefault( a => a.Coordinates.Equals( coord ) && !a.IsDeath && a.Team == Game.Turn );

						if( p != null && PtoMove == null )
						{
							PtoMove = p;
							Console.CursorLeft = MaxCoordinates.x * 4;
							Console.CursorTop = 1;
							Console.Write( "Marcado: {0},{1}", ( char )( 'A' + p.Coordinates.x ), MaxCoordinates.y - p.Coordinates.y );
							Console.CursorTop = ActualY;
							Console.CursorLeft = ActualX;
						}
						else if( PtoMove != null && p == null )
						{
							//mov = PtoMove.PossibleMoves.FirstOrDefault( a => a.End.Equals( coord ) );
							mov = Moves.FirstOrDefault( a => a.Begin.Equals( PtoMove.Coordinates ) && a.End.Equals(coord) );
						}
						else
						{
							PtoMove = null;
							Refresh();
						}
							
						break;

					default:
						Refresh();
						break;
				}
			}
				
			return mov;
		}

		public PlayerType PlayerType { get; set; }

		#endregion

		#region IBoard implementation

		public Coordinate MaxCoordinates { get; set; }

		public IGame Game { get; set; }

		public void Refresh()
		{
			Console.BackgroundColor = ConsoleColor.Black;
			Console.Clear();

			Console.WriteLine( "TURNO: {0}\n", ( Game.Turn == TeamEnum.BLACK ) ? "NEGRAS" : "BLANCAS" );

			Console.CursorLeft = 2;
			for( int c = 'A'; c < 'A' + MaxCoordinates.x; ++c )
				Console.Write( " {0} ", ( char )c );

			/*if( NMoves.HasValue )
				Console.Write( "       {0}", NMoves.Value );*/

			for( int j = 0; j < MaxCoordinates.y; ++j )
			{
				Console.CursorTop = j + 3;
				Console.CursorLeft = 0;

				Console.ForegroundColor = ConsoleColor.White;
				Console.BackgroundColor = ConsoleColor.Black;
				Console.Write( "{0} ", MaxCoordinates.y - j );

				for( int i = 0; i< MaxCoordinates.x; ++i )
				{

					if( (i + j) % 2 != 0 )
					{
						IPiece piece = ( from p in Game.Pieces where p.Coordinates.x == i && p.Coordinates.y == j && !p.IsDeath select p ).FirstOrDefault();

						if( piece != null )
						{
							Console.BackgroundColor = ConsoleColor.DarkMagenta;

							if( piece.Team == TeamEnum.WHITE )
								Console.ForegroundColor = ConsoleColor.White;
							else
								Console.ForegroundColor = ConsoleColor.Black;

							char c = (piece.Value == (int)PieceType.MAIDEN) ? 'O' : '0';

							Console.Write( " {0} ", c );
						}
						else
						{
							Console.ForegroundColor = ConsoleColor.White;
							Console.BackgroundColor = ConsoleColor.DarkMagenta;
							Console.Write( "   " );
						}
					}
					else
					{
						Console.ForegroundColor = ConsoleColor.DarkMagenta;
						Console.BackgroundColor = ConsoleColor.White;
						Console.Write( "   " );
					}
				}
			}
			Console.CursorLeft = Console.CursorLeft - 2;
		}

		public void ShowWinner( string Message )
		{
			Console.ForegroundColor = ConsoleColor.White;
			Console.BackgroundColor = ConsoleColor.DarkMagenta;

			Console.CursorLeft = 0;
			Console.CursorTop = 0;

			Console.WriteLine( Message );
			Console.WriteLine( "Pulse una tecla para continuar" );

			Console.Beep();

			Console.ReadKey();
		}

		public void SendMessage( string Message )
		{
			Console.ForegroundColor = ConsoleColor.White;
			Console.BackgroundColor = ConsoleColor.DarkMagenta;

			int x = Console.CursorLeft;
			int y = Console.CursorTop;

			Console.CursorLeft = 35;
			Console.CursorTop = 3;

			Console.WriteLine( Message );

			Console.CursorLeft = x;
			Console.CursorTop = y;
		}

		public void ShowNMoves( long Moves )
		{
			Console.ForegroundColor = ConsoleColor.White;
			Console.BackgroundColor = ConsoleColor.DarkMagenta;

			int x = Console.CursorLeft;
			int y = Console.CursorTop;

			Console.CursorLeft = 25;
			Console.CursorTop = 0;

			Console.WriteLine( "Number of Moves: {0}", Moves );

			Console.CursorLeft = x;
			Console.CursorTop = y;
		}

		#endregion
	
		/// <summary>
		/// Converts from Console coordinates to BoardCoordinates.
		/// </summary>
		/// <returns>Coordinates.</returns>
		private Coordinate ConsoleCoords2BoardCoords()
		{
			int x = ( Console.CursorLeft / 3 ) - 1;
			int y = Console.CursorTop - 3;

			return new Coordinate() { x = x, y = y };
		}
	}
}

